/**
 * Copyright 厦门中软海晟信息技术有限公司 版权所有 违者必究 2019
 */
package com.opencvjava.lessons2;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Point3;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Service;

import static com.opencvjava.support.util.CvUtils.imshow;
import static com.opencvjava.support.util.CvUtils.mat;
import static org.opencv.core.CvType.CV_32FC1;
import static org.opencv.core.CvType.CV_8UC1;
import static org.opencv.imgproc.Imgproc.TM_CCOEFF_NORMED;
import static org.opencv.imgproc.Imgproc.TM_SQDIFF;
import static org.opencv.imgproc.Imgproc.TM_SQDIFF_NORMED;
import static org.opencv.imgproc.Imgproc.rectangle;

/**
 * @author : sunzb(sunzb@hsit.com.cn)
 * @date: 2019/1/14
 */
@Service
public class TemplateMatchDemo {
    /**
     * 模板匹配 1.必须有样本 2.父图像不能有畸变,要是几何刚体(比如交通标志),比如生物细胞就就不行 3.模板和图像相对大小要合适(模板小,原图小,父图像大)
     */
    public void test() {
        Mat src = mat("template", "traffic.jpg");
        Mat template = mat("template", "flag.png");
        if (src.empty() || template.empty()) {
            throw new RuntimeException("源图读取失败");
        }
        imshow("源图", src);
        imshow("模板", template);
        int rows = src.rows() - template.rows() + 1;
        int cols = src.cols() - template.cols() + 1;
        Mat result = new Mat(rows, cols, CV_32FC1);
        int method = TM_CCOEFF_NORMED;
        Imgproc.matchTemplate(src, template, result, method);
        Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(result);
        Point maxLoc = minMaxLocResult.maxLoc;
        Point minLoc = minMaxLocResult.minLoc;

        Point matchLoc;
        if (method == TM_SQDIFF || method == TM_SQDIFF_NORMED) {
            matchLoc = minLoc;
        } else {
            matchLoc = maxLoc;
        }
        Core.normalize(result, result, 0, 1, Core.NORM_MINMAX);
        Mat result8u = new Mat();
        result.convertTo(result8u, CV_8UC1, 255);
        imshow("result", result8u);
        Mat copy = src.clone();
        rectangle(copy, matchLoc,
                new Point(matchLoc.x + template.cols(), matchLoc.y + template.rows()),
                new Scalar(0, 0, 255), 2, 8, 0);
        imshow("源图", src);
        imshow("结果", copy);
    }
}
